package com.framework.jwt;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWTSigner;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.internal.com.fasterxml.jackson.databind.ObjectMapper;
import com.eportal.domain.Sysopt;
import com.eportal.filter.AuthenticationFilter;
import com.eportal.service.SysmenuService;
import com.eportal.util.WebUtil;
import com.framework.SpringContextHolder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Saber on 2017/8/8.
 */
public class JWT {


    private static final String SECRET = "XX#$%()(#*!()!KL<><MQLMNQNQJQK sdfkjsdrow32234545fdf>?N<:{LWPW";

    private static final String EXP = "exp";

    private static final String PAYLOAD = "payload";

    //加密，传入一个对象和有效期
    public static <T> String sign(T object, long maxAge) {

        try {

            final JWTSigner signer = new JWTSigner(SECRET);
            final Map<String, Object> claims = new HashMap<String, Object>();
            ObjectMapper mapper = new ObjectMapper();
            String jsonString = mapper.writeValueAsString(object);
            claims.put(PAYLOAD, jsonString);
            claims.put(EXP, System.currentTimeMillis() + maxAge);
             return signer.sign(claims);
          } catch(Exception e) {
             return null;
          }
     }

    //加密，传入一个对象和有效期
    public static <T> String sign(T object) {

        try {
            long maxAge = 60L * 1000L * 30L; //30分钟
            final JWTSigner signer = new JWTSigner(SECRET);
            final Map<String, Object> claims = new HashMap<String, Object>();
            ObjectMapper mapper = new ObjectMapper();
            String jsonString = mapper.writeValueAsString(object);
            claims.put(PAYLOAD, jsonString);
            claims.put(EXP, System.currentTimeMillis() + maxAge);
             return signer.sign(claims);
          } catch(Exception e) {
             return null;
          }
     }

     //解密，传入一个加密后的token字符串和解密后的类型
     public static<T> T unsign(String jwt, Class<T> classT) {
         final JWTVerifier verifier = new JWTVerifier(SECRET);
         try {
             final Map<String,Object> claims= verifier.verify(jwt);
             if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
                 long exp = (Long)claims.get(EXP);
                 long currentTimeMillis = System.currentTimeMillis();
                 if (exp > currentTimeMillis) {
                     String json = (String)claims.get(PAYLOAD);
                     ObjectMapper objectMapper = new ObjectMapper();
                     return objectMapper.readValue(json, classT);
                 }
             }
             return null;
         } catch (Exception e) {
             return null;
         }

     }

    //拦截每个请求
    public static boolean check(HttpServletRequest request, HttpServletResponse response){
        response.setCharacterEncoding("utf-8");
        String token = request.getParameter("token");
        ResponseData responseData = ResponseData.ok();
        try {
            //token不存在
            if(null != token) {
                Sysopt user = JWT.unsign(token, Sysopt.class);
                String loginId = request.getParameter("loginId");
                //解密token后的loginId与用户传来的loginId不一致，一般都是token过期
                if(null != loginId && null != user) {
                    if(Integer.parseInt(loginId) == user.getSid()) {
                        setSession(user,request.getSession());
                        return true;
                    }
                    else{
                        responseData = ResponseData.forbidden();
                        responseMessage(response, response.getWriter(), responseData);
                        return false;
                    }
                } else {
                    responseData = ResponseData.forbidden();
                    responseMessage(response, response.getWriter(), responseData);
                    return false;
                }
            } else {
                responseData = ResponseData.forbidden();
                responseMessage(response, response.getWriter(), responseData);
                return false;
            }
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    //请求不通过，返回错误信息给客户端
    private static void responseMessage(HttpServletResponse response, PrintWriter out, ResponseData responseData) {
        responseData = ResponseData.forbidden();
        response.setContentType("application/json; charset=utf-8");
        String json = JSONObject.toJSONString(responseData);
        out.print(json);
        out.flush();
        out.close();
    }

    /**
     * 将用户userRole和菜单权限设置到session中
     * @param user
     * @param session
     */
    private static void setSession(Sysopt user,HttpSession session){
        int userRole=0;
        if("-1".equals(user.getIsAdmin())){
            userRole=1; //Created by Saber on 2017/8/8 下午2:38
            session.setAttribute("userRole", 1);//平台超级管理员
        }
        if("0".equals(user.getIsAdmin())){
            if(user.getrLevel()==0){
                userRole=2;//Created by Saber on 2017/8/8 下午2:38
                session.setAttribute("userRole", 2);//平台普通管理员
            }
            //区域主管
            if(user.getrLevel()==5){
                userRole=21;//Created by Saber on 2017/8/8 下午2:38
                session.setAttribute("userRole", 21);
            }
            //合作方普通管理员
            if(user.getrLevel()==1 || user.getrLevel()==3){ //物业公司 锁厂
                userRole=4;//Created by Saber on 2017/8/8 下午2:38
                session.setAttribute("userRole", 4);
            }
            //社区普通管理员
            if(user.getrLevel()==2 || user.getrLevel()==4){
                userRole=6;//Created by Saber on 2017/8/8 下午2:38
                session.setAttribute("userRole", 6);
            }
        }

        if("1".equals(user.getIsAdmin())){
            //合作方超级管理员
            if(user.getrLevel()==1 || user.getrLevel()==3){ //物业 锁厂
                userRole=3;//Created by Saber on 2017/8/8 下午2:38
                session.setAttribute("userRole", 3);
            }
            //社区超级管理员
            if(user.getrLevel()==2 || user.getrLevel()==4){
                userRole=5;//Created by Saber on 2017/8/8 下午2:38
                session.setAttribute("userRole", 5);
            }
        }

        //主板厂商 todo  Created by Saber on 2017/7/25 下午4:04
        if(user.getrLevel()==6){
            userRole=7;//Created by Saber on 2017/8/8 下午2:38
            session.setAttribute("userRole", 7);
        }

        if (user.getRoles() != null) {
            SysmenuService sysmenuService = SpringContextHolder.getBean(SysmenuService.class);
            Map<String, Object> auths = sysmenuService.loadAuths(user,userRole);
            if(auths.size()<1){
//                param.put("code", 0);
//                param.put("msg", "角色被禁用或菜单列表为空");
//                return param;
            }
            String default_access = (String) AuthenticationFilter.systemParam.get("default_access");
            auths.put("auths", auths.get("auths") + default_access);
            session.setAttribute("auths", auths);
        }
//        WebUtil.setBackgroudUser(true);
        session.setAttribute(WebUtil.IS_BACKGROUND_USER, true);
    }

}
